package com.ophiux.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ophiux.common.core.base.Result;
import com.ophiux.common.core.exception.APIException;
import com.ophiux.common.tools.util.DateUtil;
import com.ophiux.member.api.feign.IMemberFeignApi;
import com.ophiux.order.mapper.OrderMapper;
import com.ophiux.order.service.IOrderService;
import com.ophiux.order.model.dto.ProductOrderDTO;
import com.ophiux.order.model.entity.ProductOrder;
import com.ophiux.order.model.vo.ProductOrderAddVo;
import com.ophiux.order.model.vo.ProductOrderQueryVo;
import com.ophiux.order.model.vo.ProductOrderUpdateVo;
import com.ophiux.product.api.feign.IProductFeignApi;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, ProductOrder> implements IOrderService {

    @Autowired
    IProductFeignApi productFeignApi;

    @Autowired
    IMemberFeignApi memberFeignApi;


    public ProductOrderDTO covertDto(ProductOrder dto) {
        ProductOrderDTO res = new ProductOrderDTO();
        BeanUtils.copyProperties(dto, res);
        return res;
    }


    @Override
    public IPage<ProductOrderDTO> getPage(IPage<ProductOrder> iPage, ProductOrderQueryVo queryDTO) {
        LambdaQueryWrapper<ProductOrder> lambda = new LambdaQueryWrapper<ProductOrder>();
        IPage<ProductOrder> page = this.page(iPage, lambda);
        return page.convert(this::covertDto);
    }

    @Override
    public Result insert(ProductOrderAddVo vo) {
        ProductOrder data = new ProductOrder();
        BeanUtils.copyProperties(vo, data);
        int effCount = this.baseMapper.insert(data);
        if (effCount > 0) return Result.success();
        return Result.fail();
    }

    @Override
    public Result update(ProductOrderUpdateVo vo) {
        return null;
    }


    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public String createOrder(Integer amount,Boolean isException) {
        log.info("purchase begin ... xid: " + RootContext.getXID());
        //1.新增订单
        ProductOrderAddVo vo = new ProductOrderAddVo();
        vo.setProductType("2");
        vo.setMemberId(1);
        vo.setProductId(1);
        vo.setProductVersion(0);
        vo.setQuantity(1);
        vo.setOrderNo(DateUtil.getCurDateRandom());
        vo.setPayAmount(new BigDecimal(amount));
        vo.setStatus(0);
        this.insert(vo);

        //2.扣减商品库存
        Result result = productFeignApi.reduceStock(1);
        if (result.getCode() != 0) {
            throw new APIException("请求失败", "1");
        }

        //3.减少用户的余额
        Result s = memberFeignApi.updateAmount(amount);
        if (s.getCode() != 0) {
            throw new APIException(s.getMessage(), "1");
        }

        if(isException) {
            try {
                int i = 1 / 0;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                throw new APIException("服务异常", "1");
                //需要查看undo_log表数据时，需要打断点捕获这里异常，否则看不到数据
            }
        }

        return "创建订单成功,订单号："+vo.getOrderNo();
    }

}
